﻿using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Web;
using ElectronicCommerce.Framework.Utility;

namespace ElectronicCommerce.Framework.Web.ResourceManagement
{
    using QueryStringCollection = Dictionary<string, string>;
    using ElectronicCommerce.Framework.Web.Core;

    public class QueryStringBuilder
    {
        private QueryStringCollection m_QueryStringCollection = new QueryStringCollection(new CaseInsensitiveStringEqualityComparer());

        public QueryStringBuilder()
            : this(null, Encodings.UTF8)
        {
        }

        public QueryStringBuilder(Encoding contentEncoding)
            : this(null, contentEncoding)
        {
        }

        public QueryStringBuilder(NameValueCollection queryString)
            : this(queryString, Encodings.UTF8)
        {
        }

        public QueryStringBuilder(NameValueCollection queryString, Encoding contentEncoding)
        {
            if (queryString != null)
            {
                AddQueryString(queryString);
            }

            this.ContentEncoding = contentEncoding;
        }

        /// <summary>
        /// 对参数值的编码
        /// </summary>
        public Encoding ContentEncoding { get; private set; }

        /// <summary>
        /// Adds the query string.
        /// If the specified name already exists, the previous value will be replaced.
        /// </summary>
        /// <param name="paramName">Name of the param.</param>
        /// <param name="paramValue">The param value.</param>
        public void AddQueryString(string paramName, string paramValue)
        {
            if (!string.IsNullOrEmpty(paramName))
            {
                if (string.IsNullOrEmpty(paramValue))
                {
                    paramValue = string.Empty;
                }

                if (m_QueryStringCollection.ContainsKey(paramName))
                {
                    m_QueryStringCollection[paramName] = paramValue;
                }
                else
                {
                    m_QueryStringCollection.Add(paramName, paramValue);
                }
            }
        }

        /// <summary>
        /// Adds the query string.
        /// </summary>
        /// <param name="queryString"></param>
        public void AddQueryString(NameValueCollection queryString)
        {
            if (queryString != null)
            {
                foreach (string name in queryString.AllKeys)
                {
                    if (!string.IsNullOrEmpty(name))
                    {
                        string val = queryString[name];

                        if (string.IsNullOrEmpty(val))
                        {
                            val = string.Empty;
                        }

                        if (m_QueryStringCollection.ContainsKey(name))
                        {
                            m_QueryStringCollection[name] = val;
                        }
                        else
                        {
                            m_QueryStringCollection.Add(name, val);
                        }
                    }
                }
            }
        }

        public void AddQueryString(HttpNameValueCollection queryString)
        {
            if (queryString != null)
            {
                foreach (string name in queryString.Keys)
                {
                    if (!string.IsNullOrEmpty(name))
                    {
                        string val = queryString[name];

                        if (string.IsNullOrEmpty(val))
                        {
                            val = string.Empty;
                        }

                        if (m_QueryStringCollection.ContainsKey(name))
                        {
                            m_QueryStringCollection[name] = val;
                        }
                        else
                        {
                            m_QueryStringCollection.Add(name, val);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Removes the query string.
        /// </summary>
        /// <param name="paramName">Name of the param.</param>
        public void RemoveQueryString(string paramName)
        {
            if (!string.IsNullOrEmpty(paramName))
            {
                m_QueryStringCollection.Remove(paramName);
            }
        }

        /// <summary>
        /// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.object"></see>.
        /// Note: the value has been url-encoded.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.object"></see>.
        /// </returns>
        public override string ToString()
        {
            return GetHttpNameValueCollectionString(false, true);
        }

        public string ToRawString()
        {
            return GetHttpNameValueCollectionString(false, false);
        }

        private string GetHttpNameValueCollectionString(bool removeBlankValue, bool encode)
        {
            StringBuilder sb = new StringBuilder();
            string key = string.Empty;
            string value = string.Empty;
            foreach (KeyValuePair<string, string> pair in m_QueryStringCollection)
            {
                key = pair.Key;
                value = pair.Value;
                if (removeBlankValue && (string.IsNullOrEmpty(value)))
                {
                    continue;
                }

                sb.Append(encode ? Encode(key) : key);
                if (!string.IsNullOrEmpty(value))
                {
                    sb.Append("=");
                    sb.Append(encode ? Encode(value) : value);
                }
                sb.Append("&");
            }
            return sb.ToString().TrimEnd('&');
        }

        /// <summary>
        /// Gets the number of parameters.
        /// </summary>
        /// <value>The parameter count.</value>
        public int ParameterCount
        {
            get
            {
                return m_QueryStringCollection.Count;
            }
        }
        //Add by dolphin zhang
        public string this[string key]
        {
            get
            {
                if (key.IsNotEmpty())
                {
                    if (m_QueryStringCollection.ContainsKey(key))
                    {
                        return m_QueryStringCollection[key];
                    }
                }
                return string.Empty;
            }
            set
            {
                if (key.IsNotEmpty())
                {
                    if (m_QueryStringCollection.ContainsKey(key))
                    {
                        m_QueryStringCollection[key] = value;
                    }
                }
            }
        }

        #region Encode and Decode
        /// <summary>
        /// 
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static string Encode(object value)
        {
            string val = value.ToString();
            return string.IsNullOrEmpty(val) ? val : HttpUtility.UrlEncode(val);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static string Decode(string value)
        {
            string val = value.ToString();
            return string.IsNullOrEmpty(val) ? val : HttpUtility.UrlDecode(val);
        }
        #endregion
    }
}
